home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / sptexture.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  13KB  |  641 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    sptexture -
  19.  *        Stapuft comatible texture mapping support
  20.  *            
  21.  *                Paul Haeberli - 1989            
  22.  */
  23. #include "stdio.h"
  24. #include "gl.h"
  25. #include "stdio.h"
  26. #include "math.h"
  27. #include "vect.h"
  28. #include "sgiobj.h"
  29. #include "lum.h"
  30. #include "texture.h"
  31. #include "gfxmach.h"
  32.  
  33. static faket2f();
  34. static realtextureread();
  35. static faketextureread();
  36. static faketmcolor();
  37. static faketmc3f();
  38.  
  39. #define MAXTEXTURES 20
  40.  
  41. /*
  42.  *    generic texture stuff
  43.  *
  44.  */
  45. vect texavg[MAXTEXTURES+1];
  46. static int bwmode;
  47. static int fasttmp = -1;
  48.  
  49. fasttm()
  50. {
  51.     if(fasttmp>=0)
  52.     return fasttmp;
  53.     if(getgdesc(GD_TEXTURE))
  54.     fasttmp = 1;
  55.     else
  56.     fasttmp = 0;
  57.     return fasttmp;
  58. }
  59.  
  60. setbwmode(b)
  61. {
  62.     bwmode = b;
  63. }
  64.  
  65. llum(c)
  66. long c;
  67. {
  68.     int r, g, b, a, l;
  69.  
  70.     r = (c>>0 )&0xff;
  71.     g = (c>>8 )&0xff;
  72.     b = (c>>16)&0xff;
  73.     a = (c>>24)&0xff;
  74.     l = ILUM(r,g,b);
  75.     c = (a<<24)+(l*0x10101);
  76. }
  77.  
  78. vlum(c)
  79. vect *c;
  80. {
  81.     float l;
  82.  
  83.     l = LUM(c->x,c->y,c->z);
  84.     c->x = l;
  85.     c->y = l;
  86.     c->z = l;
  87. }
  88.  
  89. /*
  90.  *    general texture mapping functions 
  91.  *
  92.  *
  93.  */
  94. void myt2f(t)
  95. float *t;
  96. {
  97.     if(fasttm())
  98.     t2f(t);
  99.     else
  100.     faket2f(t);
  101. }
  102.  
  103. textureread(name,texno)
  104. char *name;
  105. int texno;
  106. {
  107.     if(fasttm())
  108.     realtextureread(name,texno);
  109.     else
  110.     faketextureread(name,texno);
  111. }
  112.  
  113. settexture(n)
  114. int n;
  115. {
  116.     if(fasttm())
  117.     realsettexture(n);
  118.     else
  119.     fakesettexture(n);
  120. }
  121.  
  122. tmcolor(c)
  123. long c;
  124. {
  125.     if(fasttm())
  126.     realtmcolor(c);
  127.     else
  128.     faketmcolor(c);
  129. }
  130.  
  131. tmc3f(c)
  132. vect *c;
  133. {
  134.     if(fasttm())
  135.     c3f((float*)c);
  136.     else
  137.     faketmc3f(c);
  138. }
  139.  
  140. /*
  141.  *    real texture mapping functions 
  142.  *
  143.  *
  144.  */
  145. static int firsted;
  146. static int texon;
  147.  
  148. static realtextureread(name,texno)
  149. char *name;
  150. int texno;
  151. {
  152.     unsigned long *imagedata;
  153.     int i, xsize, ysize;
  154.     static float texps[] = {TX_MINFILTER,TX_MIPMAP_BILINEAR,TX_MAGFILTER,TX_BILINEAR,TX_NULL};
  155.     static float texps256[] = {TX_MAGFILTER,TX_BILINEAR,TX_MINFILTER,TX_POINT,TX_WRAP,TX_CLAMP,TX_NULL};
  156.     static float tevps[] = {TV_MODULATE,TV_NULL};
  157.     char cmd[256];
  158.     float sx, sy;
  159.  
  160.     if(texno> MAXTEXTURES) {
  161.     fprintf(stderr,"textureread: texno %d exceeds maxtextures %d\n",texno);
  162.     exit(1);
  163.     }
  164.     sizeofimage(name,&xsize,&ysize);
  165.     imagedata = (unsigned long *)longimagedata(name);
  166.     lrectavg(imagedata,xsize,ysize,&texavg[texno]);
  167.     if(xsize == 256 && ysize == 256)
  168.         texdef2d(texno,4,xsize,ysize,imagedata,7,texps256);
  169.     else
  170.         texdef2d(texno,4,xsize,ysize,imagedata,5,texps);
  171.     if(!firsted) {
  172.         tevdef(1,0,tevps);
  173.         firsted = 1;
  174.     settexture(1);
  175.     }
  176. }
  177.  
  178. realsettexture(n)
  179. int n;
  180. {
  181.     if(n==0) {
  182.         texbind(0,0);
  183.         tevbind(0,0);
  184.     texon = 0;
  185.     } else {
  186.         texbind(0,n);
  187.     if(texon == 0) {
  188.             tevbind(0,1);
  189.         texon = 1;
  190.     }
  191.     }
  192. }
  193.  
  194. realtmcolor(c)
  195. long c;
  196. {
  197.     if(bwmode)
  198.     c = llum(c);
  199.     cpack(c);
  200. }
  201.  
  202. /*
  203.  *    fake texture mapping functions 
  204.  *
  205.  *
  206.  */
  207. static TEXTURE *tm[MAXTEXTURES+1];
  208. static int curtex;
  209. static float curtmr = 1.0;
  210. static float curtmg = 1.0;
  211. static float curtmb = 1.0;
  212.  
  213. static faketextureread(name,texno)
  214. char *name;
  215. int texno;
  216. {
  217.     if(texno> MAXTEXTURES) {
  218.     fprintf(stderr,"textureread: texno %d exceeds maxtextures %d\n",texno);
  219.     exit(1);
  220.     }
  221.     tm[texno] = tmopen(name);
  222.     if(tm[texno] == 0) {
  223.     fprintf(stderr,"textureread: can't open input file %s\n",name);
  224.     exit(1);
  225.     }
  226.     tmavg(tm[texno],&texavg[texno]);
  227.     curtex = texno;
  228. }
  229.  
  230. fakesettexture(n)
  231. int n;
  232. {
  233.     curtex = n;
  234. }
  235.  
  236. #define ALMOSTONE    (0.9999)
  237.  
  238. static faket2f(t)
  239. float t[2];
  240. {
  241.     vect c;
  242.  
  243.     fakettoc(t,&c);
  244.     c3f((float*)&c);
  245. }
  246.  
  247. fakettoc(t,c)
  248. float t[2];
  249. vect *c;
  250. {
  251.     vect p;
  252.  
  253.     p.x = ALMOSTONE*t[0];
  254.     p.y = ALMOSTONE*t[1];
  255.     p.z = 0.0;
  256.     tmsample(tm[curtex],&p,c);
  257.     c->x *= curtmr;
  258.     c->y *= curtmg;
  259.     c->z *= curtmb;
  260.     c->w = 1.0;
  261.     if(bwmode)
  262.        vlum(c);
  263. }
  264.  
  265. static faketmcolor(c)
  266. long c;
  267. {
  268.     curtmr = ((c>>0)&0xff)/255.0;
  269.     curtmg = ((c>>8)&0xff)/255.0;
  270.     curtmb = ((c>>16)&0xff)/255.0;
  271.     cpack(c&0xffffff);
  272. }
  273.  
  274. static faketmc3f(c)
  275. vect *c;
  276. {
  277.     curtmr = c->x;
  278.     curtmg = c->y;
  279.     curtmb = c->z;
  280.     c3f((float*)c);
  281. }
  282.  
  283. textureaverage(texno,avg)
  284. int texno;
  285. vect *avg;
  286. {
  287.     *avg = texavg[texno];
  288. }
  289.  
  290. /*
  291.  *    environment mapping stuff
  292.  *
  293.  */
  294. static int localenv;
  295.  
  296. envmaplocal(v)
  297. int v;
  298. {
  299.     
  300.     localenv = v;
  301.     if(v)
  302.     fprintf(stderr,"shade: local viewer\n");
  303.     else
  304.     fprintf(stderr,"shade: infinite viewer\n");
  305. }
  306.  
  307. xformnorm(matrix,v,tv)
  308. float matrix[4][4];
  309. vect *v, *tv;
  310. {
  311.     tv->x = v->x*matrix[0][0] + v->y*matrix[1][0] + v->z*matrix[2][0];
  312.     tv->y = v->x*matrix[0][1] + v->y*matrix[1][1] + v->z*matrix[2][1];
  313.     tv->z = v->x*matrix[0][2] + v->y*matrix[1][2] + v->z*matrix[2][2];
  314. }
  315.  
  316. xformvert(matrix,v,tv)
  317. float matrix[4][4];
  318. vect *v, *tv;
  319. {
  320.     tv->x = v->x*matrix[0][0] + v->y*matrix[1][0] + v->z*matrix[2][0] 
  321.                             + matrix[3][0];
  322.     tv->y = v->x*matrix[0][1] + v->y*matrix[1][1] + v->z*matrix[2][1]
  323.                             + matrix[3][1];
  324.     tv->z = v->x*matrix[0][2] + v->y*matrix[1][2] + v->z*matrix[2][2]
  325.                             + matrix[3][2];
  326. }
  327.  
  328. xformvert4(matrix,v,tv)
  329. float matrix[4][4];
  330. vect *v, *tv;
  331. {
  332.     tv->x = v->x*matrix[0][0] + v->y*matrix[1][0] + v->z*matrix[2][0] 
  333.                             + matrix[3][0];
  334.     tv->y = v->x*matrix[0][1] + v->y*matrix[1][1] + v->z*matrix[2][1]
  335.                             + matrix[3][1];
  336.     tv->z = v->x*matrix[0][2] + v->y*matrix[1][2] + v->z*matrix[2][2]
  337.                             + matrix[3][2];
  338.     tv->w = v->x*matrix[0][3] + v->y*matrix[1][3] + v->z*matrix[2][3]
  339.                             + matrix[3][3];
  340. }
  341.  
  342. static float vmat[4][4];
  343. static float nmat[4][4];
  344. static float psmat[4][4];
  345.  
  346. normmat(imat,normalmat)
  347. float imat[4][4];
  348. float normalmat[4][4];
  349. {
  350.     vect n, tn;
  351.     float len;
  352.     int x, y;
  353.  
  354.     n.x = 1.0;
  355.     n.y = 0.0;
  356.     n.z = 0.0;
  357.     xformnorm(imat,&n,&tn);
  358.     len = vlength(&tn);
  359.     for(y=0; y<4; y++) 
  360.     for(x=0; x<4; x++) 
  361.         normalmat[y][x] = imat[y][x]/len;
  362. }
  363.  
  364. tenvmat(mat)
  365. float *mat;
  366. {
  367.     copymat(mat,vmat);
  368.     normmat(mat,nmat);
  369. }
  370.  
  371. #define DENOM    (2.15)
  372.  
  373. tenv(n,p,t)
  374. vect *n, *p, *t;
  375. {
  376.     vect eye, tn, tp;
  377.     vect ref, ahead, half, c;
  378.     float mag, dot;
  379.  
  380.     if(!localenv) {
  381.     tn.x = n->x*nmat[0][0] + n->y*nmat[1][0] + n->z*nmat[2][0];
  382.     tn.y = n->x*nmat[0][1] + n->y*nmat[1][1] + n->z*nmat[2][1];
  383.     t->x = 0.5+tn.x/DENOM;
  384.     t->y = 0.5+tn.y/DENOM;
  385.     } else {
  386.     tn.x = n->x*nmat[0][0] + n->y*nmat[1][0] + n->z*nmat[2][0];
  387.     tn.y = n->x*nmat[0][1] + n->y*nmat[1][1] + n->z*nmat[2][1];
  388.     tn.z = n->x*nmat[0][2] + n->y*nmat[1][2] + n->z*nmat[2][2];
  389.  
  390.     eye.x = p->x*vmat[0][0] + p->y*vmat[1][0] + p->z*vmat[2][0] 
  391.                             + vmat[3][0];
  392.     eye.y = p->x*vmat[0][1] + p->y*vmat[1][1] + p->z*vmat[2][1]
  393.                             + vmat[3][1];
  394.     eye.z = p->x*vmat[0][2] + p->y*vmat[1][2] + p->z*vmat[2][2]
  395.                             + vmat[3][2];
  396. /* vnormal */
  397.      mag = sqrt(eye.x*eye.x + eye.y*eye.y + eye.z*eye.z);
  398.  
  399. /* vreflect */
  400.     dot = -2.0*(tn.x*eye.x+tn.y*eye.y+tn.z*eye.z);
  401.     ref.x = dot*tn.x+eye.x;
  402.     ref.y = dot*tn.y+eye.y;
  403.     ref.z = dot*tn.z+eye.z+mag;
  404.  
  405. /* vhalf */
  406.      mag = DENOM*sqrt(ref.x*ref.x + ref.y*ref.y + ref.z*ref.z);
  407.     if(mag<0.0001) {
  408.         t->x = 0.5;
  409.         t->y = 0.5;
  410.     } else {
  411.         t->x = 0.5+(ref.x/mag);
  412.         t->y = 0.5+(ref.y/mag);
  413.     }
  414.     }
  415. }
  416.  
  417. #define BYTEOFF(v)    (sizeof(long)*(v))
  418.  
  419. static float *envprojmat;
  420.  
  421. static envtrifunc(p0,p1,p2)
  422. long *p0, *p1, *p2;
  423. {
  424.     vect t, c0, c1, c2;
  425.  
  426.     tenv(p0+OFFSET_NORMAL,p0+OFFSET_POINT,&t);
  427.     fakettoc(&t,&c0);
  428.     tenv(p1+OFFSET_NORMAL,p1+OFFSET_POINT,&t);
  429.     fakettoc(&t,&c1);
  430.     tenv(p2+OFFSET_NORMAL,p2+OFFSET_POINT,&t);
  431.     fakettoc(&t,&c2);
  432.     bgnpolygon();
  433.     c3f((float*)&c0);
  434.     v3f((float*)(p0+OFFSET_POINT));
  435.     c3f((float*)&c1);
  436.     v3f((float*)(p1+OFFSET_POINT));
  437.     c3f((float*)&c2);
  438.     v3f((float*)(p2+OFFSET_POINT));
  439.     endpolygon();
  440. }
  441.  
  442. drawenvobj(obj,mat)
  443. sgiobj *obj;
  444. float mat[4][4];
  445. {
  446.     if(fasttm()) {
  447.     texgen(TX_S, TG_SPHEREMAP, 0);
  448.     texgen(TX_T, TG_SPHEREMAP, 0);
  449.     texgen(TX_S, TG_ON, NULL);
  450.     texgen(TX_T, TG_ON, NULL);
  451.     drawsgiobj(obj,DRAW_POINTS|DRAW_NORMALS);
  452.     texgen(TX_S, TG_OFF, NULL);
  453.     texgen(TX_T, TG_OFF, NULL);
  454.     } else {
  455.     tenvmat(mat);
  456.     applytotris(obj,envtrifunc);
  457.     }
  458. }
  459.  
  460. normtoc(n,c)
  461. vect *n, *c;
  462. {
  463.     vect tn;
  464.  
  465.     xformnorm(nmat,n,&tn);
  466.     c->x = (tn.x+1.0)/2.0;
  467.     c->y = (tn.y+1.0)/2.0;
  468.     c->z = (tn.z+1.0)/2.0;
  469. }
  470.  
  471. static trinorm(verts)
  472. float *verts[3];
  473. {
  474.     vect n0, n1, n2;
  475.  
  476.     normtoc(verts[0]+OFFSET_NORMAL,&n0);
  477.     normtoc(verts[1]+OFFSET_NORMAL,&n1);
  478.     normtoc(verts[2]+OFFSET_NORMAL,&n2);
  479.     bgnpolygon();
  480.     c3f((float*)&n0);
  481.     v3f(verts[0]+OFFSET_POINT);
  482.     c3f((float*)&n1);
  483.     v3f(verts[1]+OFFSET_POINT);
  484.     c3f((float*)&n2);
  485.     v3f(verts[2]+OFFSET_POINT);
  486.     endpolygon();
  487. }
  488.  
  489. drawnormobj(obj,mat)
  490. sgiobj *obj;
  491. float mat[4][4];
  492. {
  493.     float *p;
  494.     int npolys;
  495.     vect n0, n1, n2, n3;
  496.  
  497.     normmat(mat,nmat);
  498.     p = (float *)obj->data;
  499.     if(obj->objtype == OBJ_QUADLIST) {
  500.     npolys = (obj->nlongs/PNTLONGS)/4;
  501.     while(npolys--) {
  502.         normtoc(p+(0*PNTLONGS)+OFFSET_NORMAL,&n0);
  503.         normtoc(p+(1*PNTLONGS)+OFFSET_NORMAL,&n1);
  504.         normtoc(p+(2*PNTLONGS)+OFFSET_NORMAL,&n2);
  505.         normtoc(p+(3*PNTLONGS)+OFFSET_NORMAL,&n3);
  506.         bgntmesh();
  507.         c3f((float*)&n0);
  508.         v3f(p+(0*PNTLONGS)+OFFSET_POINT);
  509.         c3f((float*)&n1);
  510.         v3f(p+(1*PNTLONGS)+OFFSET_POINT);
  511.         c3f((float*)&n3);
  512.         v3f(p+(3*PNTLONGS)+OFFSET_POINT);
  513.         c3f((float*)&n2);
  514.         v3f(p+(2*PNTLONGS)+OFFSET_POINT);
  515.         endtmesh();
  516.         p += 4*PNTLONGS;
  517.     }
  518.     } else if(obj->objtype == OBJ_TRILIST) {
  519.     npolys = (obj->nlongs/PNTLONGS)/3;
  520.     while(npolys--) {
  521.         normtoc(p+(0*PNTLONGS)+OFFSET_NORMAL,&n0);
  522.         normtoc(p+(1*PNTLONGS)+OFFSET_NORMAL,&n1);
  523.         normtoc(p+(2*PNTLONGS)+OFFSET_NORMAL,&n2);
  524.         bgntmesh();
  525.         c3f((float*)&n0);
  526.         v3f(p+(0*PNTLONGS)+OFFSET_POINT);
  527.         c3f((float*)&n1);
  528.         v3f(p+(1*PNTLONGS)+OFFSET_POINT);
  529.         c3f((float*)&n2);
  530.         v3f(p+(2*PNTLONGS)+OFFSET_POINT);
  531.         endtmesh();
  532.         p += 3*PNTLONGS;
  533.     }
  534.     } else if(obj->objtype == OBJ_TRIMESH) {    /* could go faster */
  535.     applytomeshtris(obj,trinorm);
  536.     }
  537. }
  538.  
  539. drawprojection(obj,mat)
  540. sgiobj *obj;
  541. float mat[4][4];
  542. {
  543.     float *p;
  544.     int npolys;
  545.     vect n0, n1, n2, n3;
  546.  
  547.     p = (float *)obj->data;
  548.     tenvmat(mat);
  549.     pushmatrix();
  550.     scale(-3.0,3.0,0.0);
  551.     translate(-0.5,-0.5,0.0);
  552.     cpack(0xffffff);
  553.     drawcirc(0.5,0.5,0.5);
  554.     if(obj->objtype == OBJ_QUADLIST) {
  555.     npolys = (obj->nlongs/PNTLONGS)/4;
  556.     while(npolys--) {
  557.         tenv(p+(0*PNTLONGS)+OFFSET_NORMAL,p+(0*PNTLONGS)+OFFSET_POINT,&n0);
  558.         tenv(p+(1*PNTLONGS)+OFFSET_NORMAL,p+(1*PNTLONGS)+OFFSET_POINT,&n1);
  559.         tenv(p+(2*PNTLONGS)+OFFSET_NORMAL,p+(2*PNTLONGS)+OFFSET_POINT,&n2);
  560.         tenv(p+(3*PNTLONGS)+OFFSET_NORMAL,p+(3*PNTLONGS)+OFFSET_POINT,&n3);
  561.         bgnclosedline();
  562.         v2f((float*)&n0);
  563.         v2f((float*)&n1);
  564.         v2f((float*)&n3);
  565.         endclosedline();
  566.         bgnclosedline();
  567.         v2f((float*)&n1);
  568.         v2f((float*)&n3);
  569.         v2f((float*)&n2);
  570.         endclosedline();
  571.         p += 4*PNTLONGS;
  572.     }
  573.     } else if(obj->objtype == OBJ_TRILIST) {
  574.     npolys = (obj->nlongs/PNTLONGS)/3;
  575.     while(npolys--) {
  576.         tenv(p+(0*PNTLONGS)+OFFSET_NORMAL,p+(0*PNTLONGS)+OFFSET_POINT,&n0);
  577.         tenv(p+(1*PNTLONGS)+OFFSET_NORMAL,p+(1*PNTLONGS)+OFFSET_POINT,&n1);
  578.         tenv(p+(2*PNTLONGS)+OFFSET_NORMAL,p+(2*PNTLONGS)+OFFSET_POINT,&n2);
  579.         bgnclosedline();
  580.         v2f((float*)&n0);
  581.         v2f((float*)&n1);
  582.         v2f((float*)&n3);
  583.         endclosedline();
  584.         p += 3*PNTLONGS;
  585.     }
  586.     }
  587.     popmatrix();
  588. }
  589.  
  590. /*
  591.  *    background drawing stuff follows
  592.  *
  593.  */
  594. static int backixsize, backiysize;
  595. static unsigned long *backimgdat;
  596.  
  597. drawback(name)
  598. char *name;
  599. {
  600.     if(!backimgdat) {
  601.     sizeofimage(name,&backixsize,&backiysize);
  602.     backimgdat = (unsigned long *)longimagedata(name);
  603.     }
  604.     ortho2(0.0,1.0,0.0,1.0);
  605.     pushmatrix();
  606.     myidentity();
  607.     drawquadlimage(backimgdat,backixsize,backiysize);
  608.     popmatrix();
  609.     restorewindow();
  610. }
  611.  
  612. lrectavg(data,xsize,ysize,avg)
  613. unsigned long *data;
  614. int xsize, ysize;
  615. vect *avg;
  616. {
  617.     int n;
  618.     unsigned long rav, gav, bav, aav;
  619.  
  620.     n = xsize*ysize;
  621.     if(n>(256*256*256)) {
  622.     fprintf(stderr,"lrectavg: size too big\n");
  623.     exit(1);
  624.     }
  625.     rav = gav = bav = aav = 0;
  626.     while(n--) {
  627.     rav += ((*data)>>0)&0xff;
  628.     gav += ((*data)>>8)&0xff;
  629.     bav += ((*data)>>16)&0xff;
  630.     aav += ((*data)>>24)&0xff;
  631.     data++;
  632.     }
  633.     n = xsize*ysize;
  634.     avg->x = ((float)rav/n)/255.0;
  635.     avg->y = ((float)gav/n)/255.0;
  636.     avg->z = ((float)bav/n)/255.0;
  637.     avg->w = ((float)aav/n)/255.0;
  638.     printf("lrectavg ");
  639.     vprint(avg);
  640. }
  641.